// 路由鉴权，项目中的路由能不能被访问的权限的设置
// (某一个路由什么条件下可以被访问，什么条件下不能被访问)
// 引入路由器对象
import router from '@/router'
// 引入进度条插件
// @ts-ignore
import nprogress from 'nprogress'
// 引入进度条的样式
import 'nprogress/nprogress.css'
// 取消加载的小圆球
nprogress.configure({ showSpinner: false })
// 获取userStore中的token用于判断用户是否登录成功
import useUserStore from '@/store/modules/user'
// 在组件外访问store中的数据需要先引入pinia
import pinia from './store'
import { storeToRefs } from 'pinia'
import setting from './setting'
// 在App组件外使用获取仓库数据调用hook函数需要传递pinia（要先引入大仓库才能使用小仓库的数据）
const userStore = useUserStore(pinia)
// 获取用户名和token必须转换为响应式或使用storeToRefs
const { userName, token } = storeToRefs(userStore)
const { userInfo, userLogout } = userStore
// 全局守卫：项目中任意路由切换都会触发的钩子
// 全局前置守卫:访问某一个路由之前会执行该钩子
router.beforeEach(async (to, _from, next) => {
  // to:要访问的路由对象 from:当前路由对象 next:放行函数
  nprogress.start() // 开启进度条
  // 使用token判断用户是否已经登录
  if (token.value) {
    // 已登录不能访问/login
    if (to.path === '/login') {
      next('/home')
    } else {
      // 判断store中是否有用户数据,页面一刷新store中的数据就会丢失
      if (userName.value) {
        next() // 有用户信息直接跳转
      } else {
        // 没有用户信息就发请求获取用户信息后再放行
        try {
          // userInfo()为一个async函数返回一个Promise对象状态由返回值决定
          await userInfo()
          // 获取用户信息成功再进行放行
          // 刷新时访问异步路由，用户信息加载完毕，异步路由还未加载完毕，会出现空白效果
          next({ ...to }) // 等待路由组件加载完毕再放行
        } catch (error) {
          // 发请求不能获取到用户信息(token过期)
          // 退出登录返回登录页面
          await userLogout() // 把用户相关的数据清空
          next({ path: '/login', query: { redirect: to.path } })
        }
      }
    }
    /* 注意:next()在回调执行时只能被调用一次,next函数可以传递与to相同的配置对象,
    来更改跳转的路径如：next({name:''})next({'/path'})next(path:'') */
  } else {
    // 未登录只能访问/login并将要访问的路由以query参数的形式添加到url中,登录成功后即可访问该路由
    to.path === '/login'
      ? next()
      : next({ path: '/login', query: { redirect: to.path } })
  }
})
// 全局后置守卫
router.afterEach((to) => {
  // 设置页面标题  访问某一路由后会执行该钩子
  document.title = (setting.title.slice(0, 4) + '-' + to.meta.title) as string
  nprogress.done() //关闭进度条
})

// 第一个问题:任意一个路由的切换实现进度条业务 使用nprogress插件  pnpm i nprogress
// 第二个问题:路由鉴权(路由组件访问权限的设置)
// 全部的路由组件:登录|404|任意路由|首页|数据大屏|权限管理(三个子路由)|商品管理(四个子路由)
// 根据仓库|本地存储中的token来判断用户是否已经登录
// 用户未登录:可只可以访问/login,访问其他指向/login
// 登录成功:不能访问/login访问时指向/home,其余的路可以访问
